﻿using LCA.Community.DAL;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq;
using LCA.Community.DAL.Model;
using LCA.Community.DAL.Interfaces;
using System.Collections.Generic;
using LCA.Community.DAL.Test.ModelFactories;
using Microsoft.Practices.Unity;

namespace LCA.Community.DAL.Test
{
    /// <summary>
    ///This is a test class for GroupMembershipsRepositoryTest and is intended
    ///to contain all GroupMembershipsRepositoryTest Unit Tests
    ///</summary>
    [TestClass()]
    public class GroupMembershipsRepositoryTest : BaseTestClass
    {
        private UsersFactory _usersFactory = new UsersFactory();
        private GroupMembershipFactory _groupMembershipFactory = new GroupMembershipFactory();
        private List<User> _users;
        private GroupsFactory _groupsFactory = new GroupsFactory();
        private Group _group;
        private List<GroupMembership> _memberships;

        /// <summary>
        /// Initializes the test.
        /// </summary>
        [TestInitialize()]
        public void InitializeTest()
        {
            UnityContainerInitializer();

            var groupsRepository = _unityContainer.Resolve<IGroupsRepository>();
            var usersRepository = _unityContainer.Resolve<IUsersRepository>();
            var gMembershipsRepository = _unityContainer.Resolve<IGroupMembershipsRepository>();

            _users = _usersFactory.CreateList(10);
            _group = _groupsFactory.CreateEntity(_users[0].RowKey);

            _users.ForEach(user => usersRepository.Add(user));

            _memberships = new List<GroupMembership>();
            for(int i = 1; i < 10; i++)
            {
                var membership = _groupMembershipFactory.CreateEntity(_users[i].RowKey, _group.RowKey);
                gMembershipsRepository.Add(membership);
                _memberships.Add(membership);
            }
        }

        /// <summary>
        /// Cleans up the test.
        /// </summary>
        [TestCleanup()]
        public void CleanupTest()
        {
            var groupsRepository = _unityContainer.Resolve<IGroupsRepository>();
            var usersRepository = _unityContainer.Resolve<IUsersRepository>();
            var gMembershipsRepository = _unityContainer.Resolve<IGroupMembershipsRepository>();

            groupsRepository.DeleteTestEntities();
            usersRepository.DeleteTestEntities();
            gMembershipsRepository.DeleteTestEntities();
        }

        /// <summary>
        ///A test for DeleteAllGroupMemberships
        ///</summary>
        [TestMethod()]
        public void DeleteAllGroupMembershipsTest()
        {
            var target = _unityContainer.Resolve<IGroupMembershipsRepository>();
            string groupID = _group.RowKey;

            target.DeleteAllGroupMemberships(groupID);

            var actual = target.GetGroupMembershipByGroup(groupID);
            CollectionAssert.AreEquivalent(new List<GroupMembership>(), actual);
        }

        /// <summary>
        ///A test for DeleteAllUserMemberships
        ///</summary>
        [TestMethod()]
        public void DeleteAllUserMembershipsTest()
        {
            var target = _unityContainer.Resolve<IGroupMembershipsRepository>();
            string userID = _users[1].RowKey;

            target.DeleteAllUserMemberships(userID);

            var actual = target.GetGroupMembershipByUser(userID);
            CollectionAssert.AreEquivalent(new List<GroupMembership>(), actual);
        }

        /// <summary>
        ///A test for Get
        ///</summary>
        [TestMethod()]
        public void GetTest()
        {
            var target = _unityContainer.Resolve<IGroupMembershipsRepository>();
            
            string groupID = _group.RowKey; 
            string userID = _users[1].RowKey;
            
            GroupMembership expected = _memberships.Where( m => m.Group == groupID && m.Member == userID).First();
            GroupMembership actual;

            actual = target.Get(groupID, userID);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for GetGroupMembershipByGroup
        ///</summary>
        [TestMethod()]
        public void GetGroupMembershipByGroupTest()
        {
            var target = _unityContainer.Resolve<IGroupMembershipsRepository>();
            
            string groupID = _group.RowKey;
            List<GroupMembership> expected = _memberships;
            List<GroupMembership> actual;

            actual = target.GetGroupMembershipByGroup(groupID);
            CollectionAssert.AreEquivalent(expected, actual);
        }

        /// <summary>
        ///A test for GetGroupMembershipByUser
        ///</summary>
        [TestMethod()]
        public void GetGroupMembershipByUserTest()
        {
            var target = _unityContainer.Resolve<IGroupMembershipsRepository>();
            
            string userID = _users[1].RowKey;

            List<GroupMembership> expected = _memberships.Where(m => m.Member == userID).ToList();

            List<GroupMembership> actual;
            actual = target.GetGroupMembershipByUser(userID);
            CollectionAssert.AreEquivalent(expected, actual);
        }

        /// <summary>
        /// A test for Delete
        ///</summary>
        [TestMethod()]
        public void DeleteTest()
        {
            var target = _unityContainer.Resolve<IGroupMembershipsRepository>();

            string userID = _users[1].RowKey;
            string groupID = _group.RowKey;

            target.Delete(groupID, userID);
            var membership = target.Get(groupID, userID);

            Assert.IsNull(membership);
        }

        /// <summary>
        ///A test for Add
        ///</summary>
        [TestMethod()]
        public void AddTest()
        {
            var target = _unityContainer.Resolve<IGroupMembershipsRepository>();

            string groupID = _users[0].RowKey;
            string userID = _group.RowKey;

            target.Add(groupID, userID);

            var actual = target.Get(groupID, userID);
            Assert.AreEqual(actual.Member, userID);
            Assert.AreEqual(actual.Group, groupID);
        }
    }
}
